package com.example.war;

import java.util.Random;

import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.util.Log;

public class Soldier {
    private Quad mHead;
    private Quad mShoulder;
    private Quad mLeftArm;
    private Quad mRightArm;
    private Quad mHands;
    private Quad mBody;
    private Breathe mBreathe;
    private Context mContext;
    private OldFire mFire;
    private Fires mFires;
    private Point mScrSize;
    private float mBodyPosY;
    private static final int BODY_HEIGHT = 699;
    private static final int ACTION_INHALE = 1;
    private static final int ACTION_BREATH = 2;
    private static final float INHALE_DURATION = 600f;
    private static final float BREATH_DURATION = 800f;
    private static final int HEAD_ANIM_DIST = 4;
    private static final int SHOULDER_AMIN_DIST = 4;
    private static final int ARM_ANIM_ANGLE = 2;
    private int mAction = ACTION_INHALE;
    private long mStartTime = -1;
    private long mCurTime = -1;
    private float mSoulderInitPosY;
    private float mHeadInitPosY;
    private float mLeftArmInitAngle;
    private float mRightArmInitAngle;
    
    
    public Soldier(Context context, GL10 gl) {
        mContext = context;
        mHead = new Quad(false);
        mShoulder = new Quad(false);
        mLeftArm = new Quad(false);
        mRightArm = new Quad(false);
        mHands = new Quad(false);
        mBody = new Quad(false);
        mBreathe = new Breathe(context, gl, BREATH_DURATION);
        mFire = new OldFire(context, gl);
        //mFires = new Fires(context, gl);
        initQuad(gl, mHead, R.raw.head);
        initQuad(gl, mShoulder, R.raw.shoulder);
        initQuad(gl, mLeftArm, R.raw.left_arm);
        initQuad(gl, mRightArm, R.raw.right_arm);
        initQuad(gl, mHands, R.raw.hands);
        initQuad(gl, mBody, R.raw.body);
        mScrSize = Utils.getScreenSize(context);
        mBodyPosY = -(mScrSize.y - BODY_HEIGHT)/2.0f;
    }
    
    private void initQuad(GL10 gl, Quad quad, int resId) {
        Bitmap bitmap = Utils.loadRawImage(mContext.getResources(), resId);
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        quad.setSize(width, height);
        quad.setTexture(gl, bitmap, false);
        bitmap.recycle();
    }
    
    private void drawHead(GL10 gl) {
        long timeOff = mCurTime - mStartTime;
        float yPosOff = 0; 
        if (mAction == ACTION_INHALE) {
            yPosOff = -HEAD_ANIM_DIST*(timeOff/INHALE_DURATION);
        } else if (mAction == ACTION_BREATH) {
            yPosOff = HEAD_ANIM_DIST*(timeOff/BREATH_DURATION);
        }
        gl.glPushMatrix();
        gl.glTranslatef(-7, mHeadInitPosY + yPosOff, 0); // 240
        mHead.draw(gl, 0, 0, 0, 0, true);
        gl.glPopMatrix();
    }
    
    private void drawShoulder(GL10 gl) {
        long timeOff = mCurTime - mStartTime;
        float yPosOff = 0; 
        if (mAction == ACTION_INHALE) {
            yPosOff = SHOULDER_AMIN_DIST*(timeOff/INHALE_DURATION);
        } else if (mAction == ACTION_BREATH) {
            yPosOff = -SHOULDER_AMIN_DIST*(timeOff/BREATH_DURATION);
        }
        
        gl.glPushMatrix();
        //gl.glRotatef(5, 0, 0, 1.0f);
        gl.glTranslatef(0, mSoulderInitPosY+yPosOff, 0); // 142
        mShoulder.draw(gl, 0, 0, 0, 0, true);
        gl.glPopMatrix();
    }
    
    private void drawLeftArm(GL10 gl) {
        long timeOff = mCurTime - mStartTime;
        float zRotAngle = 0; 
        if (mAction == ACTION_INHALE) {
            zRotAngle = ARM_ANIM_ANGLE*(timeOff/INHALE_DURATION);
        } else if (mAction == ACTION_BREATH) {
            zRotAngle = -ARM_ANIM_ANGLE*(timeOff/BREATH_DURATION);
        }
        
        gl.glPushMatrix();
        gl.glTranslatef(-140, mBodyPosY+332, 0); //92
        gl.glPushMatrix();
        gl.glTranslatef(60, 20, 0);
        gl.glRotatef(mLeftArmInitAngle+zRotAngle, 0, 0, 1.0f);
        gl.glTranslatef(-60, -20, 0);
        mLeftArm.draw(gl, 0, 0, 0, 0, true);
        gl.glPopMatrix();
        gl.glPopMatrix();
    }
    
    private void drawRightArm(GL10 gl) {
        long timeOff = mCurTime - mStartTime;
        float zRotAngle = 0; 
        if (mAction == ACTION_INHALE) {
            zRotAngle = -ARM_ANIM_ANGLE*(timeOff/INHALE_DURATION);
        } else if (mAction == ACTION_BREATH) {
            zRotAngle = ARM_ANIM_ANGLE*(timeOff/BREATH_DURATION);
        }
        
        gl.glPushMatrix();
        gl.glTranslatef(135, mBodyPosY+308, 0);//78
        gl.glPushMatrix();
        gl.glTranslatef(-60, -20, 0);
        gl.glRotatef(mRightArmInitAngle+zRotAngle, 0, 0, 1.0f);
        gl.glTranslatef(60, 20, 0);
        mRightArm.draw(gl, 0, 0, 0, 0, true);
        gl.glPopMatrix();
        gl.glPopMatrix();
    }

    private void initActionStartState(int action) {
        if (action == ACTION_INHALE) {
            mAction = ACTION_INHALE;
            mSoulderInitPosY = mBodyPosY+376;
            mHeadInitPosY = mBodyPosY+530;
            mLeftArmInitAngle = -ARM_ANIM_ANGLE/2f;
            mRightArmInitAngle = ARM_ANIM_ANGLE/2f;
            mStartTime = mCurTime;
        } else {
            mAction = ACTION_BREATH;
            mSoulderInitPosY = mBodyPosY+380;
            mHeadInitPosY = mBodyPosY+526;
            mLeftArmInitAngle = ARM_ANIM_ANGLE/2f;
            mRightArmInitAngle = -ARM_ANIM_ANGLE/2f;
            mStartTime = mCurTime;
            mBreathe.reset(mCurTime + 150);
        }
    }
    
    public void draw(GL10 gl) {
        mCurTime = System.currentTimeMillis();
        if (mStartTime == -1) {
            initActionStartState(ACTION_INHALE);
        } else {
            long elapseTime = mCurTime - mStartTime;
            if (mAction == ACTION_INHALE) {
                if (elapseTime > INHALE_DURATION) {
                    initActionStartState(ACTION_BREATH);
                }
            } else if (mAction == ACTION_BREATH) {
                if (elapseTime > BREATH_DURATION) {
                    initActionStartState(ACTION_INHALE);
                }
            }
        }
        // Deal with other resolution(not 720x1280)
    	gl.glPushMatrix();
    	gl.glTranslatef(0, -mScrSize.y/2, 0);
    	float scale = mScrSize.x / 720f;
    	gl.glScalef(scale, scale, 1);
    	gl.glTranslatef(0, mScrSize.y/2, 0);
    	
    	if (mIsDither) {
    	    calculateDither();
    	    gl.glPushMatrix();
    	    gl.glTranslatef(mSoldierOffsetX, mSoldierOffsetY, 0);
    	}
    	
    	// Draw Body
        mBody.draw(gl, 0, 0, mBodyPosY, 0, true);
        
        // Draw Shoulder
        drawShoulder(gl);
        
        //Draw Head
        drawHead(gl);
        
        // Draw Hands
        gl.glPushMatrix();
        gl.glTranslatef(-4, mBodyPosY+376, 0); // 123
        mHands.draw(gl, 0, 0, 0, 0, true);
        gl.glPopMatrix();
        
        //Draw Arms
        drawLeftArm(gl);
        drawRightArm(gl);
        
        // Draw Breathe
        gl.glPushMatrix();
        gl.glTranslatef(0, mBodyPosY + 410, 0);
        mBreathe.draw(gl);
        gl.glPopMatrix();
        
        // Draw Fire
        mFire.draw(gl);
        //mFires.draw(gl);
        
        gl.glPopMatrix();
        if (mIsDither) {
            gl.glPopMatrix();
            if (System.currentTimeMillis() - mDitherStartTime >= mAnimDuration) {
                mIsDither = false;
            }
        }
    }
    
    private float mSoldierOffsetX;
    private float mSoldierOffsetY;
    private long mDitherStartTime;
    private long mLastDrawTime;
    private float mDitherStep;
    private boolean mIsDither;
    private int mAnimDuration;
    public void startDither(long start, int duration) {
        mIsDither = true;
        mAnimDuration = duration;
        mLastDrawTime = mDitherStartTime = start;
        mDitherStep = -30;
    }
    
    private void calculateDither() {
        long currentTime = System.currentTimeMillis();
        long elapsed = currentTime - mDitherStartTime;
        if (elapsed >= mAnimDuration) {
            mSoldierOffsetX = 0;
            mSoldierOffsetY = 0;
        } else if (currentTime - mLastDrawTime > 20) {
            mLastDrawTime = currentTime;
            Random random = new Random();
            random.setSeed(currentTime+1000);
            mSoldierOffsetX = -20+random.nextInt(40);
            random.setSeed(currentTime+3000);
            mSoldierOffsetY = -20+random.nextInt(40);
            //mSoldierOffsetX += mDitherStep;
            //mDitherStep = -mDitherStep;
        }
    }
    
    public void clean(GL10 gl) {
        mBreathe.clean(gl);
        mHead.deleteTexture(gl);
        mBody.deleteTexture(gl);
        mLeftArm.deleteTexture(gl);
        mRightArm.deleteTexture(gl);
        mHands.deleteTexture(gl);
        mShoulder.deleteTexture(gl);
    }
}
